package com.xuantian.baoming.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.xuantian.baoming.entity.OrderInfo;
import com.xuantian.baoming.enums.OrderStatus;
import com.xuantian.baoming.enums.wxpay.WxNotifyType;
import com.xuantian.baoming.mapper.OrderInfoMapper;
import com.xuantian.baoming.service.OrderInfoService;
import com.xuantian.baoming.service.PaymentInfoService;
import com.xuantian.baoming.service.WxJsapiService;
import com.xuantian.baoming.util.OrderNoUtils;
import com.xuantian.baoming.util.UserAgentUtil;
import com.xuantian.baoming.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@Service
public class WxJsapiServiceImpl implements WxJsapiService {

    @Autowired
    private CloseableHttpClient wxPayClient;

    @Autowired
    private com.xuantian.baoming.config.wxPayConfig wxPayConfig;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private PaymentInfoService paymentInfoService;

    private final ReentrantLock lock = new ReentrantLock();

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Value("${totalFee}")
    private Integer totalFee;

    @Override
    public R<Map<String,Object>> jsapiPay(String code, OrderInfo orderInfo1) {

        log.info("jsapi---生成订单");


        //查询用户是否已经下单并且成功支付, 如果已经支付直接返回
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInfo::getName, orderInfo1.getName());
        wrapper.eq(OrderInfo::getContact, orderInfo1.getContact());
        wrapper.eq(OrderInfo::getStatus, OrderStatus.SUCCESS.getType());
        Integer integer = orderInfoMapper.selectCount(wrapper);
        if (integer > 0){
            return R.fail(500, "已经报名成功,请勿重新报名!");
        }

        //一个人只记录一条数据，避免一个人多次下单，存储多条数据在成数据冗余
        String  openId = null;
        try {
            openId = UserAgentUtil.getOpenId(code);
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
        //查询用户已下单，但未支付，则取消订单
        orderInfo1.setOrderNo(OrderNoUtils.getOrderNo());//订单号
        orderInfo1.setStatus(OrderStatus.NOTPAY.getType());//支付状态
        orderInfo1.setTotalFee(totalFee);//金额
        //生成订单
        OrderInfo orderInfo = orderInfoService.createOrder(orderInfo1);


        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(wxPayConfig.getConfig()).build();
        // 跟之前下单示例一样，填充预下单参数
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setCurrency("CNY");
        amount.setTotal(orderInfo.getTotalFee());
        Payer payer = new Payer();
        payer.setOpenid(openId);

        request.setAppid(wxPayConfig.getAppid());
        request.setMchid(wxPayConfig.getMchId());
        request.setAmount(amount);
        request.setDescription("诗词比赛报名费");
        request.setOutTradeNo(orderInfo.getOrderNo());
        request.setPayer(payer);
        request.setNotifyUrl(wxPayConfig.getNotifyDomain().concat(WxNotifyType.JSAPI_NOTIFY.getType()));
        // response包含了调起支付所需的所有参数，可直接用于前端调起支付
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);

        HashMap<String, Object> map = new HashMap<>();
        map.put("response", response);
        map.put("orderNo",orderInfo.getOrderNo());

        return R.ok(map);
    }
}